package com.crimerank;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.crimerank.data.StopCrime;
import com.crimerank.data.ParcelableGeoPoint;
import com.google.android.maps.GeoPoint;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class Stations extends BaseListActivity {
	private MetroStationAdapter m_adapter;
	private ArrayList<GeoPoint> points = new ArrayList<GeoPoint>();
	double lat, lon;
	Bundle loc;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.stations);

		// Get lat/long from the Intent extras
		this.loc = getIntent().getExtras().getBundle("loc");
		lat = loc.getDouble("lat");
		lon = loc.getDouble("lon");

		// Setup the list adapter
		m_adapter = new MetroStationAdapter(this, R.layout.stationsrow,
				new ArrayList<StopCrime>());
		setListAdapter(m_adapter);

		// Request data from server
		requestData(lat, lon, 5);
	}

	private void requestData(double lat, double lon, int count) {
		try {
			// form the URL and query parameters
			String url = getResources().getString(
					R.string.URL_NEAREST_METROSTATION);
			String query = String.format("lat=%s&lon=%s&count=%s",
					URLEncoder.encode(Double.toString(lat), "UTF-8"),
					URLEncoder.encode(Double.toString(lon), "UTF-8"),
					URLEncoder.encode(Integer.toString(count), "UTF-8"));

			// Perform the HTTP request
			String result = doHttpRequest(url, query);

			// Process results and display list
			processJson(result);
		} catch (JSONException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Intent myIntent = new Intent(v.getContext(), StationPrediction.class);
		myIntent.putExtra("loc", loc);
		
		// Send station code and name.
		myIntent.putExtra("StopCrimeObj", m_adapter.getItem(position));

		// Send current location and the metro station selected by the user.
		Bundle loc = getIntent().getExtras().getBundle("loc");
		Double startLat = new Double(loc.getDouble("lat"));
		Double startLon = new Double(loc.getDouble("lon"));
		String startLatLon = startLat.toString() + "," + startLon.toString();
		Double finishLat = new Double(points.get(position).getLatitudeE6()
				/ (double) 1000000);
		Double finishLon = new Double(points.get(position).getLongitudeE6()
				/ (double) 1000000);
		String finishLatLon = finishLat.toString() + "," + finishLon.toString();
		myIntent.putExtra("start", startLatLon);
		myIntent.putExtra("finish", finishLatLon);

		// Original method, sending all points in a list.
		ArrayList<ParcelableGeoPoint> pointsExtra = new ArrayList<ParcelableGeoPoint>();
		pointsExtra.add(new ParcelableGeoPoint(points.get(position)));
		myIntent.putExtra("points", pointsExtra);

		startActivityForResult(myIntent, 0);
	}

	public void processJson(String str) throws JSONException {
		m_adapter.clear();
		points.clear();

		// Loop thru JSON array and parse out bus stops
		JSONArray ja = new JSONArray(str);
		for (int i = 0; i < ja.length(); i++) {
			// Get metro crime data
			JSONObject jo = (JSONObject) ja.get(i);
			StopCrime stationCrime = new StopCrime();
			stationCrime.setCrimeAggregate(jo.getString("crimeAggregate"));
			stationCrime.setTotal(jo.getInt("total"));
			stationCrime.setDistance(jo.getInt("distance"));

			// Get metro station data
			JSONObject tmp = jo.getJSONObject("metroStop");
			//MetroStation station = new MetroStation();
			stationCrime.setName(tmp.getString("name"));
			stationCrime.setStop_id(tmp.getString("code"));
			stationCrime.setLocation(tmp.getString("location"));
			stationCrime.addRoute(tmp.getString("line_code_1"));
			stationCrime.addRoute(tmp.getString("line_code_2"));
			stationCrime.setGid(tmp.getInt("gid"));
			stationCrime.setRail(true);

			points.add(stationCrime.getLocation());

			// Add metro station crime data to list
			m_adapter.add(stationCrime);
		}
	}

	private class MetroStationAdapter extends ArrayAdapter<StopCrime> {

		private ArrayList<StopCrime> items;

		public MetroStationAdapter(Context context, int textViewResourceId,
				ArrayList<StopCrime> items) {
			super(context, textViewResourceId, items);
			this.items = items;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = convertView;
			if (view == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				view = vi.inflate(R.layout.stationsrow, null);
			}

			StopCrime stop = items.get(position);

			if (stop != null) {
				TextView textName = (TextView) view
						.findViewById(R.id.stationName);
				TextView textDist = (TextView) view
						.findViewById(R.id.stationDist);
				TextView textRank = (TextView) view
					.findViewById(R.id.stationRank);
				ImageView lineColor1 = (ImageView) view
						.findViewById(R.id.lineColor1);
				ImageView lineColor2 = (ImageView) view
						.findViewById(R.id.lineColor2);

				if (textName != null && textDist != null && textRank != null) {
					textName.setText(stop.getName());

					String str = String.format("(%1.2f mi)",
							stop.getDistance() * 0.000621371192);
					textDist.setText(str);
					textRank.setText("Rank: " + stop.getRank());
				}
				if (lineColor1 != null && lineColor2 != null) {
					List<String> routes = stop.getRoutes();
					String lineColor = routes.get(0);
					lineColor1.setImageResource(getlineColorIcon(lineColor));
					if(routes.size() == 2){
						lineColor = routes.get(1);
						lineColor2.setImageResource(getlineColorIcon(lineColor));
					}
				}
			}

			return view;
		}

		private int getlineColorIcon(String color) {
			if (color.equals("BL")) {
				return R.drawable.blue_b;
			} else if (color.equals("OR")) {
				return R.drawable.orange_b;
			} else if (color.equals("RD")) {
				return R.drawable.red_b;
			} else if (color.equals("YL")) {
				return R.drawable.yellow_b;
			} else if (color.equals("GR")) {
				return R.drawable.green_b;
			}

			return R.drawable.null_b;

		}

	}

	public void onClick(View v) {
		Intent myIntent;
		switch (v.getId()) {
		case (R.id.imageMap):
			myIntent = new Intent(v.getContext(), Map.class);
			myIntent.putExtra("loc", loc);
			ArrayList<ParcelableGeoPoint> pointsExtra = new ArrayList<ParcelableGeoPoint>();
			for (GeoPoint point : points) {
				pointsExtra.add(new ParcelableGeoPoint(point));
			}

			myIntent.putExtra("mapType", "geoPoint");
			myIntent.putExtra("points", pointsExtra);
			startActivityForResult(myIntent, 0);
			break;
		case (R.id.imageHome):
			myIntent = new Intent(v.getContext(), Home.class);
			myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivityForResult(myIntent, 0);
			break;
		case (R.id.imageMore):
			int nRecords = m_adapter.getCount();
			requestData(lat, lon, nRecords + 5);
			onContentChanged();
			break;
		}
	}
}